import os
import sys 
import textwrap
from PIL import Image,ImageDraw,ImageFont


class xhsImage():
    def __init__(self):
        import json
        config_path = os.path.join(os.path.dirname(__file__), 'configs', 'dd.config')
        with open(config_path, 'r', encoding='utf-8') as f:
            config = json.load(f)
        self.work_dir = config['work_dir']
        
        self.logo_text='学习星球·苔花社'
        self.font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'SIMHEI.TTF')
        

    def generate_bg(self, ratio='3:4', bg_color='#293931', bg_img=None):
        if bg_img:
            # print("使用图片背景...")
            # print(f"原始图片尺寸: {bg_img.size}, 模式: {bg_img.mode}")
            # 使用图片背景
            if ratio == '3:4':
                size = (720, 960)
            elif ratio == '4:3':
                size = (960, 720)
            else:
                size = (720, 960)
            
            # print(f"目标尺寸: {size}")
            # 缩放图片到目标尺寸
            bg_img = bg_img.resize(size, Image.LANCZOS)
            # print(f"缩放后尺寸: {bg_img.size}")
            img = bg_img.convert('RGBA')
            # print(f"转换后模式: {img.mode}")
        else:
            # 使用颜色背景
            if ratio == '3:4':
                img=Image.new('RGBA',(720,960),bg_color)
            elif ratio == '4:3':
                img=Image.new('RGBA',(960,720),bg_color)
            else:
                img=Image.new('RGBA',(720,960),bg_color)
            
        # 添加logo和文字
        logo=Image.open(os.path.join(os.path.dirname(__file__),'configs','dd_logo.png'))
        logo=logo.resize((80,80))
        mask=logo.split()[3]
        img.paste(logo,(50,70),mask=mask)

        draw=ImageDraw.Draw(img)
        font = ImageFont.truetype(self.font_path, 28)
        draw.text((150,100), self.logo_text, font=font, fill='#e9ede8')
        return img        

    
    def generate_txt(self, image, text='', region=(60,80,900,700), initial_font='黑体',initial_font_size=25, color="white", min_font_size=10, intended='yes'):
        """
        在图片的指定区域内绘制文字，支持：
        1. 自动换行和标点避头尾（首字符不出现标点，除引号括号外）
        2. 可选段落首行空两格（intended参数控制）
        3. 垂直居中显示
        4. 自动调整字体大小直至匹配
        
        :param image: PIL Image 对象
        :param text: 要绘制的文字
        :param region: 区域坐标 (x1, y1, x2, y2)
        :param initial_font_size: 初始字体大小
        :param color: 文字颜色
        :param min_font_size: 最小允许的字体大小
        :param intended: 是否首行缩进 ('yes'/'no')
        :return: 修改后的Image对象
        """

        

        def is_prohibited_punctuation(char):
            """检查字符是否为禁止出现在行首的标点（除引号、括号外）"""
            prohibited = "，。、；：？！…—.,;:?!"  # 需要避头尾的标点
            allowed = "\"'‘“”()（）【】"  # 允许出现在行首的符号
            return char in prohibited and char not in allowed

        draw = ImageDraw.Draw(image)
        if initial_font=='黑体':
            font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'SIMHEI.TTF')
        elif initial_font=='times':
            font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'times.ttf')
        x1, y1, x2, y2 = region
        width = x2 - x1
        height = y2 - y1
        
        # 尝试不同的字体大小，从大到小
        for font_size in range(initial_font_size, min_font_size - 1, -1):
            try:
                font = ImageFont.truetype(font_path, font_size)
                line_height = font_size * 1.8
                avg_char_width = font_size * 0.7  # 调整字符宽度估算
                
                # 处理段落和自动换行
                wrapped_lines = []
                for paragraph in text.split('\n'):
                    if not paragraph.strip():
                        wrapped_lines.append("")
                        continue
                    
                    # 添加首行缩进（如果需要）
                    current_para = "　　" + paragraph.strip() if intended == 'yes' else paragraph.strip()
                    
                    # 逐字符处理避免标点出现在行首
                    current_line = []
                    for char in current_para:
                        test_line = "".join(current_line + [char])
                        test_width = draw.textlength(test_line, font=font)
                      
                        # 需要换行的情况（宽度超出或遇到换行符）
                        if test_width > width or char == "\n":
                            # 处理标点避头尾
                            if current_line and is_prohibited_punctuation(current_line[0]):
                                if wrapped_lines:
                                    wrapped_lines[-1] += current_line[0]
                                    current_line = current_line[1:]
                            
                            if current_line:
                                wrapped_lines.append("".join(current_line))
                                current_line = []
                            
                            if char != "\n":
                                current_line.append(char)
                        else:
                            current_line.append(char)
                    
                    # 添加最后一行
                    if current_line:
                        wrapped_lines.append("".join(current_line))
                
                # 计算总高度
                total_height = len(wrapped_lines) * line_height
                
                # 检查高度并绘制
                if total_height <= height:
                    start_y = y1 + (height - total_height) // 2
                    y = start_y
                    for line in wrapped_lines:
                        draw.text((x1, y), line, font=font, fill=color)
                        y += line_height
                    return image
                    
            except Exception as e:
                continue
        
        raise ValueError(f"无法在字体大小{min_font_size}-{initial_font_size}范围内使文本适应区域高度")

    def dd_image(self,txt,region,initial_font,font_size,color,intended='yes',ratio='3:4',bg_color='#293931',bg_img=None):
        # print(f"调用dd_image - bg_img: {bg_img is not None}")
        img=self.generate_bg(ratio=ratio, bg_color=bg_color, bg_img=bg_img)
        # print(f"生成的背景尺寸: {img.size}, 模式: {img.mode}")
        # 根据比例调整文字区域
        if ratio == '3:4':
            region = (100, 190, 620, 850)  # 适合3:4比例的文本区域
        elif ratio == '4:3':
            region = (100, 190, 860, 590)  # 适合4:3比例的文本区域
        res_img=self.generate_txt(img,txt,region,initial_font=initial_font,initial_font_size=font_size,color=color,intended=intended)
        return res_img    

class xhsCover():
    def __init__(self):
        self.aspect_ratio = '16:9'  # 默认16:9

    def bg(self):
        if self.aspect_ratio == '4:3':
            return Image.new('RGBA', (960, 720), "#FFFFFF")
        elif self.aspect_ratio == '16:9':
            return Image.new('RGBA', (1280, 720), "#FFFFFF")
        elif self.aspect_ratio == '3:4':
            return Image.new('RGBA', (720, 960), "#FFFFFF")
        else:  # 9:16
            return Image.new('RGBA', (720, 1280), "#FFFFFF")
    
    def deal_cover_img(self, cover_img):
        bg = self.bg()
        bg_width, bg_height = bg.size
        width, height = cover_img.size
        target_ratio = bg_width / bg_height
        img_ratio = width / height
        
        # 根据比例差异决定缩放策略
        if img_ratio > target_ratio:
            # 图片比目标宽，按高度缩放
            new_height = bg_height
            new_width = int(width * (new_height / height))
        else:
            # 图片比目标高，按宽度缩放
            new_width = bg_width
            new_height = int(height * (new_width / width))
        
        # 高质量缩放
        cover_img = cover_img.resize((new_width, new_height), Image.LANCZOS)
        
        # 计算裁剪区域(从中心裁剪)
        left = (new_width - bg_width) // 2
        top = (new_height - bg_height) // 2
        right = left + bg_width
        bottom = top + bg_height
        
        # 裁剪并返回
        return cover_img.crop((left, top, right, bottom))
        
        # 将处理后的图片粘贴到背景中央
        bg_width, bg_height = bg.size
        cover_width, cover_height = cover_img.size
        position = ((bg_width - cover_width) // 2, (bg_height - cover_height) // 2)
        bg.paste(cover_img, position)
        
        return bg


    def put_title_1(self, img, main_title, main_title_font, main_title_size, main_title_color,
                    sub_title, sub_title_font, sub_title_size, sub_title_color, opacity=100):
        # 确保图片是RGBA模式以支持透明度
        if img.mode != 'RGBA':
            img = img.convert('RGBA')
        
        # 创建透明图层
        overlay = Image.new('RGBA', img.size, (0,0,0,0))
        draw = ImageDraw.Draw(overlay)
        
        # 根据图片尺寸计算黑色矩形尺寸和位置
        img_width, img_height = img.size
        if img_width == 960 and img_height == 720:  # 4:3
            square_width = 500
            square_height = 700
            x = img.width - square_width - 10  # 右边距10px
            y = 10  # 上边距10px
        elif img_width == 1280 and img_height == 720:  # 16:9
            square_width = 700
            square_height = 700
            x = img.width - square_width - 10  # 右边距10px
            y = 10  # 上边距10px
        elif img_width == 720 and img_height == 960:  # 3:4
            square_width = 700
            square_height = 500
            x = (img.width - square_width) // 2  # 水平居中
            y = img.height - square_height - 10  # 下边距10px
        else:  # 9:16 (720x1280)
            square_width = 700
            square_height = 700
            x = (img.width - square_width) // 2  # 水平居中
            y = img.height - square_height - 10  # 下边距10px
            
        square_width = int(square_width)
        square_height = int(square_height)
        radius = 20  # 圆角半径
        alpha = int(255 * (opacity / 100))
        square_color = (0, 0, 0, alpha)
        
        # 绘制圆角矩形
        # 1. 绘制四个圆角
        draw.ellipse([(x, y), (x + radius*2, y + radius*2)], fill=square_color)
        draw.ellipse([(x + square_width - radius*2, y), (x + square_width, y + radius*2)], fill=square_color)
        draw.ellipse([(x, y + square_height - radius*2), (x + radius*2, y + square_height)], fill=square_color)
        draw.ellipse([(x + square_width - radius*2, y + square_height - radius*2), (x + square_width, y + square_height)], fill=square_color)
        
        # 2. 绘制矩形主体
        draw.rectangle(
            [(x + radius, y), (x + square_width - radius, y + square_height)],
            fill=square_color
        )
        draw.rectangle(
            [(x, y + radius), (x + square_width, y + square_height - radius)],
            fill=square_color
        )
        
        # 设置字体路径
        if main_title_font == '黑体':
            main_font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'SIMHEI.TTF')
        else:
            main_font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'times.ttf')
            
        if sub_title_font == '黑体':
            sub_font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'SIMHEI.TTF')
        else:
            sub_font_path = os.path.join(os.path.dirname(__file__), 'fonts', 'times.ttf')
        
        # 加载字体
        main_font = ImageFont.truetype(main_font_path, main_title_size)
        sub_font = ImageFont.truetype(sub_font_path, sub_title_size)
        
        # 设置边距
        main_margin = 32
        sub_margin = 32
        text_area_width = square_width - 2 * main_margin
        
        def smart_wrap(text, font, max_width):
            """智能换行，处理多行文本且不截断英文单词"""
            final_lines = []
            
            # 先按用户输入的换行符分割段落
            paragraphs = text.split('\n')
            
            for paragraph in paragraphs:
                if not paragraph.strip():
                    final_lines.append("")
                    continue
                    
                lines = []
                current_line = []
                current_word = ""
                
                # 预处理段落，移除所有换行符和回车符
                paragraph = paragraph.replace('\r', '').replace('\n', '')
                for char in paragraph:
                    # 判断是否是英文单词的一部分
                    if char.isalpha() or char == "'":
                        current_word += char
                    else:
                        if current_word:  # 处理当前英文单词
                            test_line = ''.join(current_line + [current_word])
                            test_width = draw.textlength(test_line, font=font)
                            if test_width <= max_width:
                                current_line.append(current_word)
                            else:
                                if current_line:  # 当前行不为空，先保存当前行
                                    lines.append(''.join(current_line))
                                    current_line = []
                                # 尝试将整个单词放入新行
                                word_width = draw.textlength(current_word, font=font)
                                if word_width <= max_width:
                                    current_line.append(current_word)
                                else:  # 单词太长，强制分割
                                    for c in current_word:
                                        test_line = ''.join(current_line + [c])
                                        test_width = draw.textlength(test_line, font=font)
                                        if test_width <= max_width:
                                            current_line.append(c)
                                        else:
                                            lines.append(''.join(current_line))
                                            current_line = [c]
                            current_word = ""
                        
                        # 处理非字母字符
                        test_line = ''.join(current_line + [char])
                        test_width = draw.textlength(test_line, font=font)
                        if test_width <= max_width:
                            current_line.append(char)
                        else:
                            lines.append(''.join(current_line))
                            current_line = [char]
                
                # 处理最后一个单词
                if current_word:
                    test_line = ''.join(current_line + [current_word])
                    test_width = draw.textlength(test_line, font=font)
                    if test_width <= max_width:
                        current_line.append(current_word)
                    else:
                        if current_line:
                            lines.append(''.join(current_line))
                            current_line = []
                        word_width = draw.textlength(current_word, font=font)
                        if word_width <= max_width:
                            current_line.append(current_word)
                        else:
                            for c in current_word:
                                test_line = ''.join(current_line + [c])
                                test_width = draw.textlength(test_line, font=font)
                                if test_width <= max_width:
                                    current_line.append(c)
                                else:
                                    lines.append(''.join(current_line))
                                    current_line = [c]
                
                if current_line:
                    lines.append(''.join(current_line))
                
                final_lines.extend(lines)
            
            return final_lines

        # 计算上下半区高度
        half_height = square_height // 2
        top_half_y = y
        bottom_half_y = y + half_height

        # 处理主标题自动换行（智能不截断英文单词）
        main_lines = smart_wrap(main_title, main_font, text_area_width)

        # 计算主标题总高度
        main_total_height = len(main_lines) * main_title_size * 1.1  # 1.1倍行距
        main_start_y = top_half_y + (half_height - main_total_height) // 2

        # 绘制主标题（多行）
        main_y = main_start_y
        for line in main_lines:
            line_width = draw.textlength(line, font=main_font)
            line_x = x + (square_width - line_width) // 2
            draw.text((line_x, main_y), line, font=main_font, fill=main_title_color)
            main_y += main_title_size * 1.1  # 主标题行间距

        # 处理副标题自动换行（智能不截断英文单词）
        sub_lines = smart_wrap(sub_title, sub_font, text_area_width)

        # 副标题从下半部分顶部开始
        sub_start_y = bottom_half_y + sub_margin

        # 绘制副标题（多行）
        sub_y = sub_start_y
        for line in sub_lines:
            line_width = draw.textlength(line, font=sub_font)
            line_x = x + (square_width - line_width) // 2
            draw.text((line_x, sub_y), line, font=sub_font, fill=sub_title_color)
            sub_y += sub_title_size * 1.5  # 副标题行间距
        
        # 将透明图层与原图混合
        img = Image.alpha_composite(img, overlay)
        return img


    def generate_cover(self, cover_img, main_title, main_title_font, main_title_color,
                      sub_title, sub_title_font, sub_title_color, sub_title_size=42,
                      main_title_size=78, opacity=100, aspect_ratio='16:9'):
        self.aspect_ratio = aspect_ratio
        # 确保主标题字体大小在70-120范围内且为偶数
        main_title_size = max(70, min(120, main_title_size))
        main_title_size = main_title_size // 2 * 2  # 确保是2的倍数
        
        # 保留换行符用于段落分割
        main_title = main_title.replace('\r', '')
        sub_title = sub_title.replace('\r', '')
        img=self.deal_cover_img(cover_img=cover_img)
        cover=self.put_title_1(img=img,
                              main_title=main_title,
                              main_title_font=main_title_font,
                              main_title_size=main_title_size,
                              main_title_color=main_title_color,
                              sub_title=sub_title,
                              sub_title_font=sub_title_font,
                              sub_title_size=sub_title_size,
                              sub_title_color=sub_title_color,
                              opacity=opacity)
        return cover

if __name__=='__main__':
#     p=xhsImage()
#     txt='''
# 你只有时时记得向内看，向内修
# 心越强大，就越懂得放手一切不对的人和事。
# 从而及时的设立你的边界，跳出纠缠的场域
# 保有能量得以专注你的目标。
#         '''
#     img=p.dd_image(txt=txt,region=(100,130,800,700),initial_font='黑体',font_size=36,color='white',intended='yes')
#     img.show()
    
    p=xhsCover()
    cover=p.generate_cover(r'D:\temp\lz_temp\square.jpg')
    # cover=p.deal_cover_img(r'D:\temp\lz_temp\00heng.jpg')
    cover.show()
